const nftModel = require('../model/nftModel')
const gridModel = require('../model/gridModel')
const userModel = require('../model/userModel')
const {bfmetaSDK} = require('../util/util')
// 首先查找有无未完成的nft
// 如果存在未完成则返回nft和对应全部格子信息，如果不存在未完成的则新建待完成一个nft
// 当前添加格子的时候如果count = 100 说明nft生成 complete 置为1并且将该nft上链 然后在数据库中新建一个待完成nft
const uncompleteNft = () => {
    return async (req, res, next) => {
        try {
            var [nft] = await nftModel.uncompleteNft()
            // 如果不存在待完成nft则创建一个
            if(nft.length == 0){
                await nftModel.createNft()
            }
            // 再次获取待完成nft
            [nft] = await nftModel.uncompleteNft()
            // 获取待完成nft的grid
            const [grids] = await gridModel.getGrids(nft[0]._id)
            res.json({nft, grids})
        } catch (error) {
            next(error)
        }
    }
}

const addGrid = () => {
    return async (req, res, next) => {
        try {
            // 添加的格子信息
            const grid = req.body
            // 当前在操作的nft
            const [nft] = await nftModel.nft(grid.nftId)
            // 当前在操作的nft的数量
            nft[0].count ++
            // 添加格子信息
            await gridModel.addGrid(grid)
            // 更新nft
            await nftModel.updateNft(nft[0])
            res.status(201).send({grid})
        } catch (error) {
            next(error)
        }
    }
}

const completeNFT = () => {
    return async (req, res, next) => {
        try {
            const [nfts] = await nftModel.nft(req.body.nftId)
            const nft = nfts[0]
            const address = req.body.address
            const [user] = await userModel.getUserByAddress(address)
            const keypair = await bfmetaSDK.bfchainSignUtil.createKeypair(user[0].words)
            const publicKey = keypair.publicKey.toString('hex')
            const secretKey = keypair.secretKey
            // 上链
            const data={
                "publicKey": publicKey,
                "fee":"2000",
                "applyBlockHeight":1,
                "factoryId": 'nftcreater10520',
                "entityId": nft.createAt,
                "recipientId": address           
            }
            const buffer = await createNFT(data) 
            const result = await BNFT(buffer, secretKey)
            console.log(result)
            // 修改完成字段
            if(result.success){
                nft.complete = 1
                nft.owner = address
                nft.description = 'this is id :' + nft._id + "NFT in nftcreater10520" 
                nft.name = 'nftcreater10520_' + nft.createAt
                nft.img = 'http://8.129.37.177:3000/img/' + req.file.filename
                await nftModel.updateNft(nft)
                await nftModel.createNft()
            }
            res.status(201).send({result})
        } catch (error) {
            next(error)
        }
    }
}

//生成NFT
const createNFT = async (data) => {
    try {   
        const NFTresult = await bfmetaSDK.api.transaction.createIssueEntity(data);
        // console.log(NFTresult)
        const buffer = NFTresult.result.buffer;
        return buffer
      } catch (error) {
        next(error)
      }
} 
//广播NFT
const BNFT = async (buffer, secretKey)  => {
    const bytes = Buffer.from(buffer, "base64")
    const signature = (await bfmetaSDK.bfchainSignUtil.detachedSign(bytes, secretKey)).toString("hex");
    const broadcastResult= await bfmetaSDK.api.transaction.broadcastIssueEntity({
        "buffer": buffer,
        "signature": signature
    })
    return broadcastResult
}

const nfts = () => {
    return async (req, res, next) => {
        try {
           const [nfts] = await nftModel.nfts()
           res.json({nfts})
        } catch (error) {
            next(error)
        }
    }
}

module.exports = {uncompleteNft, addGrid, completeNFT, createNFT,BNFT, nfts}